package com.bdqn.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.bdqn.pojo.SysRole;
import com.bdqn.pojo.SysUser;
import com.bdqn.service.SysRoleService;
import com.bdqn.service.SysUserService;
import com.bdqn.util.Constants;
import com.bdqn.util.Page;

import com.mysql.cj.util.StringUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.apache.log4j.Logger;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 用户控制类
 *
 * @aurhor Administrator  whs
 * @since 2024/7/30
 */
@Controller
@RequestMapping(value = "/user")
public class SysUserController {

    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysRoleService sysRoleService;

    private Logger logger = Logger.getLogger(SysUserController.class);

    /**
     * 多部件文件上传（错误信息临时保存在request作用域 uploadFileError属性中）
     *
     * @param uploadPath 需要上传的位置
     * @param multipartFile 需要上传的文件对象
     * @param msg 存储错误信息
     * @return 成功返回地址 ，失败返回null表示文件上传失败
     */
    public synchronized String multipartFileUpload(String uploadPath, MultipartFile multipartFile, Map<String, String> msg){

        String uploadFilePath = null; // 文件上传地址，返回null表示文件上传失败

        // 定义文件存放目录
        logger.debug("上传文件路径：" + uploadPath);

        if (!multipartFile.isEmpty()) {
            // 获取上传的文件信息
            String originalFile = multipartFile.getOriginalFilename(); // 原文件名称
            logger.debug("原文件名称为：" + originalFile);
            String prefix = FilenameUtils.getExtension(originalFile); // 原文件后缀
            logger.debug("原文件后缀为：" + prefix);
            long fileSize = multipartFile.getSize(); // 原文件大小
            logger.debug("上传文件大小：" + fileSize);

            // 判断上传的文件是否符合要求
            if (fileSize > Constants.MAX_FILE_SIZE) { // 上传文件大小不能超过500KB
                msg.put("uploadFileError", " * 上传文件大小不得超过 5MB");
                return uploadFilePath;
            }
            if (prefix != null && !(prefix.equalsIgnoreCase("jpg") || prefix.equalsIgnoreCase("jpeg") || prefix.equalsIgnoreCase("png") || prefix.equalsIgnoreCase("pneg"))) {
                msg.put("uploadFileError", " * 上传文件格式只能是jpg、jpeg、png、pneg");
                return uploadFilePath;
            }

            // 确定文件存储名称
            String fileName = System.nanoTime() + RandomUtils.nextInt(1000) + "_Personal." + prefix;
            logger.debug("新生成的文件名为：" + fileName);

            // 将上传的文件保存到目标位置
            File targetFile = new File(uploadPath);
            if (!targetFile.exists()) {
                targetFile.mkdirs(); // 如果目录不存在则生成目录
            }
            // 保存文件
            try {
                // 存储物理地址 + 生成的文件名称
                multipartFile.transferTo(new File(targetFile, fileName));
            } catch (IOException e) {
                e.printStackTrace();
                msg.put("uploadFileError", " * 文件上传失败！");
                return uploadFilePath;
            }
            // 文件上传完成就可以拿到地址
            uploadFilePath = "/" + Constants.UPLOAD_PATH + "/" + fileName;
        }

        // 返回文件上传成功后的地址，失败时返回null，并且将失败信息记录到
        return uploadFilePath;
        //        String uploadFilePath = null; // 文件上传地址 失败返回null表示文件上传失败
//        //定义存放路径
//        logger.debug("文件上传路径："+uploadPath);
//
//        if(!multipartFile.isEmpty()){
//            //获取文件上传的文件信息
//            String originalFile = multipartFile.getOriginalFilename();  // 原文件名
//            logger.debug("原文件名为" + originalFile);
//            String prefix = FilenameUtils.getExtension(originalFile); // 原文件后缀
//            logger.debug("原文件后缀为" + prefix);
//            long fileSize = multipartFile.getSize(); // 原文件大小
//            logger.debug("原文件大小为" + fileSize);
//
//            // 判断文件上传是否符合要求
//            if (fileSize > Constants.MAX_FILE_SIZE){ // 上传文件大小不能超过500KB
//                msg.put("uploadFileError"," * 上传文件大小不能超过 5MB");
//                return uploadFilePath;
//            }
//            // 判断文件的后缀
//            if (!(prefix.equalsIgnoreCase("jsp") || prefix.equalsIgnoreCase("jpeg") ||  prefix.equalsIgnoreCase("png") ||  prefix.equalsIgnoreCase("pneg"))){
//                msg.put("uploadFileError", " * 上传文件格式只能是jpg、jpeg、png、pneg");
//                return uploadFilePath;
//            }
//
//            // 确定文件存储名字
//            String fileName = System.nanoTime() + RandomUtils.nextInt(1000) + "_Personal." + prefix ;
//            logger.debug("新生成的文件名字" + fileName);
//
//            //将上传的文件保存到目标位置
//            File targetFile = new File(uploadPath);
//            if (!targetFile.exists()){  // 如果目录不存在则生成目录
//                targetFile.mkdirs();
//            }
//
//            // 保存文件
//            try {
//                // 存储物理地址 + 生成文件名称
//                multipartFile.transferTo(new File(targetFile,fileName));
//            }catch (IOException e){
//                e.printStackTrace();
//                msg.put("uploadFileError"," * 文件上传失败！");
//                return uploadFilePath;
//            }
//
//            //文件上传完成后就可以拿到地址
//            uploadFilePath = "/" + Constants.UPLOAD_PATH + "/" + fileName ;
//        }
//        // 返回文件上传后成功的地址 ， 失败时返回 null
//        return uploadFilePath;
    }



    /**
     * 查询用户
     */
    @GetMapping("/list")
    public String list(HttpServletRequest request,Model model, @RequestParam(value = "queryRealName",required = false) String queryRealName , @RequestParam(value = "queryRoleId",required = false) Long queryRoleId , @RequestParam(value = "pageIndex",required = false,defaultValue = "1") Integer pageIndex) {
        List<SysUser> userList = null;
        Page<SysUser> page = new Page(); // 构建分页对象
        try {
            // 获取所有角色信息填充下拉列表
            List<SysRole> roleList = sysRoleService.list();
            // 查询符合条件的总用户数据量
            int count = sysUserService.count(queryRealName,queryRoleId);
            System.out.println("-->  count = "+count);
            page.setTotalCount(count); // 设置总页数
            // 先设置总数据量再设置页码
            page.setCurrentPageNo(pageIndex); // 当前页数
            int pageSize = page.getPageSize();  // 获取页面容量 5
            // 查询分页数据
            userList = sysUserService.selectPageList(queryRealName,queryRoleId,pageIndex,pageSize);
            page.setList(userList); // 将对象传入分页对象
            int totalPageCount = page.getTotalCount(); // 获取总页数

            model.addAttribute("roleList", roleList);   // 填充角色下拉列表
            model.addAttribute("queryRealName",queryRealName); // 查询条件回显
            model.addAttribute("queryRoleId",queryRoleId);
            model.addAttribute("userList", userList); // 用户信息
            model.addAttribute("page",page); // 分页对象

            model.addAttribute("totalCount",totalPageCount);
            model.addAttribute("totalPageCount",pageSize);
            model.addAttribute("currentPageNo",pageIndex);

        }catch (Exception e) {
            e.printStackTrace();
            logger.error(e);
            return "redirect:/frame";
        }
        return "sysUser/list";
    }


    /**
     * 去到添加页面
     */
    @GetMapping("/add")
    public String toAdd(Model model) {
        // 获取所有角色信息填充下拉列表
        List<SysRole> roleList = sysRoleService.list();
        model.addAttribute("roleList", roleList);
        return "sysUser/add";
    }

    /**
     * 添加用户信息
     * @param model
     * @return
     */

    @PostMapping("/add")
    public String toAdd(Model model, HttpServletRequest request, HttpSession session, SysUser sysUser, MultipartFile idPic, MultipartFile workPic){

        SysUser loginSysUser = (SysUser) session.getAttribute(Constants.USER_SESSION);
        sysUser.setCreatedUserId((long) loginSysUser.getId());
        sysUser.setCreatedTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));

        // 文件上传到服务器的真实位置
        String uploadPath = session.getServletContext().getRealPath(Constants.UPLOAD_PATH);
        System.out.println("\n\n\n idPic =  "+ idPic);
        Map<String,String> msg = new HashMap<>();
        // 身份证照片上传
        if (idPic != null) {
            // 提取文件上传的方法
            String idPicPath = multipartFileUpload(uploadPath, idPic, msg);
            // Web访问的路径（不是文件上传的磁盘位置）
            if (idPicPath == null) {
                String uploadFileError = msg.get("uploadFileError");
                request.setAttribute("idPicUploadError", uploadFileError);
                return "sysUser/add";
            }
            // 设置身份证照片路径
            sysUser.setIdPicPath(idPicPath);
        }
        // 工作证照片上传
        if (workPic != null) {
            // 提取文件上传的方法
            String workPicPath = multipartFileUpload(uploadPath, workPic, msg);
            // Web访问的路径（不是文件上传的磁盘位置）
            if (workPicPath == null) {
                String uploadFileError = msg.get("uploadFileError");
                request.setAttribute("workPicUploadError", uploadFileError);
                return "sysUser/add";
            }
            // 设置工作证照片路径
            sysUser.setWorkPicPath(workPicPath);
        }

        // 调用业务逻辑层完成用户添加
        boolean flag = sysUserService.add(sysUser);
        if (flag) { // 成功重定向到列表页
            return "redirect:/user/list";
        }
        return "sysUser/add";
    }


    /**
     * 去到 用户查看详情页面
     */
    @GetMapping("/view/{id}")
    public String userView(Model model, @PathVariable Integer id) {
        logger.debug("根据用户id查询用户的详情信息"+id);
        SysUser sysUser = sysUserService.getUserById(id);
        model.addAttribute(sysUser);
        return "sysUser/view";
    }

    /**
     * 跳转到【修改】用户信息页面
     */
    @GetMapping("/toUpdate")
    public String toUpdate(@RequestParam Integer uid,Model model) {
        logger.debug("跳转到修改用户信息页面");
        SysUser sysUser = sysUserService.getUserById(uid);
        model.addAttribute(sysUser);
        return "sysUser/update";
    }

    /**
     * 修改用户信息
     */
    @PostMapping("/update")
    public String modifySave(HttpSession session,SysUser sysUser) {
        sysUser.setUpdatedUserId((long) ((SysUser)session.getAttribute(Constants.USER_SESSION)).getId());
        sysUser.setUpdatedTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        if (sysUserService.update(sysUser)){
            return "redirect:/user/list";
        }
        return "sysUser/update";

    }

    /**
     * 使用ajax 验证账号是否存在 1存在
     * @param account
     * @return
     */
    @ResponseBody
    @GetMapping("/exist")
    public String exist(String account) {
        int exist = -1;
        try {
            // 调用业务逻辑层完成判断
            boolean flag = sysUserService.exist(account);
            if (flag) { // 账号已存在
                exist = 1;
            } else { // 账号不存在
                exist = 0;
            }
        } catch (RuntimeException e) {
            exist = -1;
        }
        // 将数据封装为JSON格式返回
        return JSONObject.of("exist", exist).toString();
    }

    /**
     * 使用ajax 异步请求然后返回JSON数据
     */
    @ResponseBody
    @GetMapping(value = "/{id}/view",produces = {"application/json;charset=UTF-8"})
    public Object view(@PathVariable Integer id) {
        StringHttpMessageConverter s = null;
        logger.debug("根据用户id查询用户的详情信息"+id);
        String sysUserJson = "" ;
        if (id == null || id.equals("")) {
            return "nodata";
        }else {
            try {
                SysUser sysUser = sysUserService.getUserById(id);
                sysUserJson = JSON.toJSONString(sysUser);
                logger.debug("用户的详情信息转换为JSON："+sysUserJson);
            }catch (Exception e){
                e.printStackTrace();
                return "failed";
            }
            return "sysUserJson";
        }
    }

    /**
     *跳转到修改页面
     */
    @GetMapping("/toUpdatePwd")
    public String toUpdatePwd(){
        return "sysUser/updatePassword";
    }

    /**
     * Ajax异步调用的处理接口 用来判断用户输入的密码是否正确
     * @param
     * @return
     */
    @ResponseBody
    @PostMapping("/checkOldPwd")
    public String checkOldPwd(HttpSession session,@RequestParam("oldPassword") String oldPwd){
        // 判断Session是否过期
        if (session != null && !session.isNew()) {
            long lastAccessedTime = session.getLastAccessedTime();
            int maxInactiveInterval = session.getMaxInactiveInterval();
            long now = System.currentTimeMillis();
            if (now - lastAccessedTime > maxInactiveInterval * 1000) {
                return JSONObject.of("result", "sessionerror").toString();
            }
        }

        // 获取user对象
        SysUser loginSysUser = (SysUser) session.getAttribute(Constants.USER_SESSION);
        if (oldPwd != null && oldPwd.equals(loginSysUser.getPassword())) {
            return JSONObject.of("result", "true").toString();
        } else {
            return JSONObject.of("result", "false").toString();
        }
////        // 判断输入的新密码是否和用户密码一致
////        if (oldPassword != null && !oldPassword.equals(loginSysUser.getPassword())) {
////            return JSONObject.of("request", "true").toString();
////        }
//        System.out.println("oldpassword = " + oldpassword);
//        if (loginSysUser == null) {
//            request.put("result", "sessionerror");
//        } else if (StringUtils.isNullOrEmpty(oldpassword)) {
//            request.put("result", "error");
//        } else {
//            if (oldpassword.equals(loginSysUser.getPassword())) {
//                request.put("result", "true");
//            } else {
//                request.put("result", "false");
//            }
//        }
//        // 将数据封装为JSON格式返回
//        return JSONObject.of("request", "false").toString();
    }


    /**
     * 保存修改的密码
     */
    @PostMapping("/savePassword")
    public String savePassword(HttpSession session,@RequestParam("newPassword") String newPassword){
        SysUser sysUser = new SysUser();

        sysUser.setUpdatedUserId((long) ((SysUser)session.getAttribute(Constants.USER_SESSION)).getId());
        sysUser.setUpdatedTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));

        sysUser.setPassword(newPassword);

        sysUser.setId(((SysUser)session.getAttribute(Constants.USER_SESSION)).getId());

        boolean flag = sysUserService.update(sysUser);
        if (flag){
            return "redirect:/login";
        }else {
            return "/sysUser/updatePassword";
        }
    }

    /**
     * Ajax异步删除用户
     *
     * @param userId
     * @return
     */
    @ResponseBody
    @DeleteMapping("/del/{userId}")
    public String del(HttpSession session, @PathVariable("userId") Integer userId) {
        String uploadPath = session.getServletContext().getRealPath(Constants.UPLOAD_PATH);
        int result = 0;
        try {
            result = sysUserService.del(uploadPath, userId); // -1表示不存在，1表示成功，0表示失败
        } catch (RuntimeException e) {
            result = 0;
            logger.error(e.getMessage());
        }
        return JSONObject.of("delResult", result == -1 ? "notexist" : result == 1 ? "true" : "false").toString();
    }


}
